/*
-----------------------------------------------------------------------------
Filename:    TutorialApplication.cpp
-----------------------------------------------------------------------------

This source file is part of the
   ___                 __    __ _ _    _ 
  /___\__ _ _ __ ___  / / /\ \ (_) | _(_)
 //  // _` | '__/ _ \ \ \/  \/ / | |/ / |
/ \_// (_| | | |  __/  \  /\  /| |   <| |
\___/ \__, |_|  \___|   \/  \/ |_|_|\_\_|
      |___/                              
      Tutorial Framework
      http://www.ogre3d.org/tikiwiki/
-----------------------------------------------------------------------------
*/
#include "stdafx.h"
#include "TutorialApplication.h"
#include "GameObject.h"

#include <math.h>

//-------------------------------------------------------------------------------------
TutorialApplication::TutorialApplication(void)
{
}
//-------------------------------------------------------------------------------------
TutorialApplication::~TutorialApplication(void)
{
}


/*
//-------------------------------------------------------------------------------------
void TutorialApplication::createCamera(void)
{
}
 
//-------------------------------------------------------------------------------------
void TutorialApplication::createViewports(void)
{
}
*/

//-------------------------------------------------------------------------------------
void TutorialApplication::createScene(void)
{
	Ogre::MaterialManager& lMaterialManager = Ogre::MaterialManager::getSingleton();
	Ogre::String lNameOfResourceGroup = "myResourceGroup";
	{
		Ogre::ResourceGroupManager& lRgMgr = Ogre::ResourceGroupManager::getSingleton();
		lRgMgr.createResourceGroup(lNameOfResourceGroup);
		Ogre::String lDirectoryToLoadTextures = "../../media/textures";
		bool lIsRecursive = false;
		lRgMgr.addResourceLocation(lDirectoryToLoadTextures, "FileSystem", lNameOfResourceGroup, lIsRecursive);
		lRgMgr.initialiseResourceGroup(lNameOfResourceGroup);
		lRgMgr.loadResourceGroup(lNameOfResourceGroup);
	}
	{
		// this creation is not perfect (as you will see in a later tutorial about manualresourceloader).
		Ogre::MaterialPtr lMaterial = lMaterialManager.create("myMaterial",lNameOfResourceGroup);
		Ogre::Technique* lFirstTechnique = lMaterial->getTechnique(0);
		Ogre::Pass* lFirstPass = lFirstTechnique->getPass(0);
		lFirstPass->setLightingEnabled(true);
		lFirstPass->setSceneBlending(Ogre::SBT_TRANSPARENT_ALPHA);
		lFirstPass->setDepthWriteEnabled(false);
		lFirstPass->setDiffuse(1, 1, 0, 0.2);
	}

	createSphere("mySphereMesh", 10, 64, 64);
	Ogre::Entity* sphereEntity = mSceneMgr->createEntity("mySphereEntity", "mySphereMesh");
	Ogre::SceneNode* sphereNode = mSceneMgr->getRootSceneNode()->createChildSceneNode();
	sphereEntity->setMaterialName("myMaterial");
	sphereNode->attachObject(sphereEntity);
	
    // create your scene here :)
	Ogre::Entity* ogreHead = mSceneMgr->createEntity("Head", "ogrehead.mesh");
	
    Ogre::SceneNode* headNode = mSceneMgr->getRootSceneNode()->createChildSceneNode();
	
    headNode->attachObject(ogreHead);

	GameObject *jacob = new GameObject(headNode);
	//statisk GameObject jacob(headNode);
	jacob->move(100,0,0);

    // Set ambient light
    mSceneMgr->setAmbientLight(Ogre::ColourValue(0.5, 0.5, 0.5));
 
    // Create a light
    Ogre::Light* l = mSceneMgr->createLight("MainLight");
    l->setPosition(20,80,50);
}

void TutorialApplication::createSphere(const std::string& strName, const float r, const int nRings, const int nSegments)
	{
		Ogre::ManualObject * manual = mSceneMgr->createManualObject(strName);
		manual->begin("BaseWhiteNoLighting", Ogre::RenderOperation::OT_TRIANGLE_LIST);
 
		float fDeltaRingAngle = (Ogre::Math::PI / nRings);
		float fDeltaSegAngle = (2 * Ogre::Math::PI / nSegments);
		unsigned short wVerticeIndex = 0 ;
 
		// Generate the group of rings for the sphere
		for( int ring = 0; ring <= nRings; ring++ ) 
		{
			float r0 = r * sinf (ring * fDeltaRingAngle);
			float y0 = r * cosf (ring * fDeltaRingAngle);
 
			 // Generate the group of segments for the current ring
			for(int seg = 0; seg <= nSegments; seg++) {
				 float x0 = r0 * sinf(seg * fDeltaSegAngle);
				 float z0 = r0 * cosf(seg * fDeltaSegAngle);
 
             // Add one vertex to the strip which makes up the sphere
             manual->position( x0, y0, z0);
             manual->normal(Ogre::Vector3(x0, y0, z0).normalisedCopy());
             manual->textureCoord((float) seg / (float) nSegments, (float) ring / (float) nRings);
 
             if (ring != nRings) {
                 // each vertex (except the last) has six indicies pointing to it
                 manual->index(wVerticeIndex + nSegments + 1);
                 manual->index(wVerticeIndex);               
                 manual->index(wVerticeIndex + nSegments);
                 manual->index(wVerticeIndex + nSegments + 1);
                 manual->index(wVerticeIndex + 1);
                 manual->index(wVerticeIndex);
                 wVerticeIndex ++;
			}
         } // end for seg
     } // end for ring
     manual->end();
     Ogre::MeshPtr mesh = manual->convertToMesh(strName);
     mesh->_setBounds( Ogre::AxisAlignedBox( Ogre::Vector3(-r, -r, -r), Ogre::Vector3(r, r, r) ), false );
 
     mesh->_setBoundingSphereRadius(r);
        unsigned short src, dest;
        if (!mesh->suggestTangentVectorBuildParams(Ogre::VES_TANGENT, src, dest))
        {
                  mesh->buildTangentVectors(Ogre::VES_TANGENT, src, dest);
        }
 }


#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
#define WIN32_LEAN_AND_MEAN
#include "windows.h"
#endif

#ifdef __cplusplus
extern "C" {
#endif

#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
    INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT )
#else
    int main(int argc, char *argv[])
#endif
    {
        // Create application object
        TutorialApplication app;

        try {
            app.go();
        } catch( Ogre::Exception& e ) {
#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
            MessageBox( NULL, e.getFullDescription().c_str(), "An exception has occured!", MB_OK | MB_ICONERROR | MB_TASKMODAL);
#else
            std::cerr << "An exception has occured: " <<
                e.getFullDescription().c_str() << std::endl;
#endif
        }

        return 0;
    }

#ifdef __cplusplus
}
#endif
